using System.Linq;
using Godot;

namespace Arcane.Source.UI
{
    [Tool]
    [GlobalClass]
    public partial class FlowGridContainer : Container
    {
        public enum SpacingMode
        {
            Pixel, Percentage
        }

        private int _column = 1;
        [Export]
        int Column
        {
            get => _column;
            set
            {
                _column = value;
                Recalculate();
                FitsChildren();
            }
        }
        [Export] SpacingMode spacingMode;
        private double _spacing;
        [Export]
        double Spacing
        {
            get => _spacing;
            set
            {
                _spacing = value;

                Recalculate();
                FitsChildren();
            }
        }
        private double _paddingLeft;
        [Export]
        double PaddingLeft
        {
            get => _paddingLeft;
            set
            {
                _paddingLeft = value;
                Recalculate();
                FitsChildren();
            }
        }
        private double _paddingRight;
        [Export]
        double PaddingRight
        {
            get => _paddingRight;
            set
            {
                _paddingRight = value;
                Recalculate();
                FitsChildren();
            }
        }
        private double _paddingTop;
        [Export]
        double PaddingTop
        {
            get => _paddingTop;
            set
            {
                _paddingTop = value;
                RecalculateBounds();
                FitsChildren();
            }
        }
        private double _paddingBottom;
        [Export]
        double PaddingBottom
        {
            get => _paddingBottom;
            set
            {
                _paddingBottom = value;
                RecalculateBounds();
                FitsChildren();
            }
        }



        private double _cellSize;
        private double _pixelSpacing;
        private double _pixelPaddingLeft;
        private double _pixelPaddingRight;
        private double _pixelPaddingTop;
        private double _pixelPaddingBottom;

        public override void _Notification(int what)
        {
            if (what == NotificationChildOrderChanged)
            {
                RecalculateBounds();
                FitsChildren();
            }

            if (what == NotificationResized)
            {
                Recalculate();
                FitsChildren();
            }
        }

        public void Recalculate()
        {
            RecalculateCellSize();
            RecalculateBounds();
        }

        public void RecalculateBounds()
        {
            Remeasure();
            int row = Mathf.CeilToInt((double)GetChildCount() / Column);
            CustomMinimumSize = new(0, (float)(row * _cellSize + (row - 1) * _pixelSpacing + _pixelPaddingTop + _pixelPaddingBottom));
        }

        public void Remeasure()
        {
            float width = GetRect().Size.X;

            switch (spacingMode)
            {
                case SpacingMode.Percentage:
                    _pixelSpacing = width * _spacing;
                    _pixelPaddingLeft = width * _paddingLeft;
                    _pixelPaddingRight = width * _paddingRight;
                    _pixelPaddingTop = width * _paddingTop;
                    _pixelPaddingBottom = width * _paddingBottom;
                    break;

                default:
                    _pixelSpacing = _spacing;
                    _pixelPaddingLeft = _paddingLeft;
                    _pixelPaddingRight = _paddingRight;
                    _pixelPaddingTop = _paddingTop;
                    _pixelPaddingBottom = _paddingBottom;
                    break;
            }
        }

        public void RecalculateCellSize()
        {
            _cellSize = (GetRect().Size.X - _pixelPaddingLeft - _pixelPaddingRight - (Column - 1) * _pixelSpacing) / Column;
        }

        public void FitsChildren()
        {
            var interval = _pixelSpacing + _cellSize;
            var cellSize = (float)_cellSize * Vector2.One;
            var i = 0;
            foreach (var child in GetChildren().Cast<Control>())
            {
                int col = i % Column;
                int row = i / Column;

                FitChildInRect(child, new((float)(_pixelPaddingLeft + col * interval), (float)(_pixelPaddingTop + row * interval), cellSize));
                i += 1;
            }
        }

        // public override void _Draw()
        // {
        //     var interval = _pixelSpacing + _cellSize;
        //     var cellSize = (float)_cellSize * Vector2.One;
        //     DrawRect(new(0, 0, GetRect().Size), Colors.White);
        //     var childCount = GetChildCount();
        //     var row = Mathf.CeilToInt((double)childCount / _column);
        //     for (int r = 0; r < row; r++)
        //     {
        //         for (int c = 0; c < _column; c++)
        //         {
        //             if ((r * _column + c) < childCount) 
        //                 DrawRect(new((float)(_paddingLeft + c * interval), (float)(_paddingTop + r * interval), cellSize), Colors.Black);
        //         }
        //     }
        // }
    }
}